﻿using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reflection;
using System.Security.Permissions;
using System.Text;
using Isuka.Linq;

namespace Isuka.Reflection
{
    /// <summary>
    /// CodeDom ヘルパー
    /// </summary>
    public static class CodeDomHelper
    {
        public static CodeMemberMethod MethodInfoToCodeDom(MethodInfo methodInfo)
        {
            Contract.Requires<ArgumentNullException>(methodInfo != null, "methodInfo");

            var result = new CodeMemberMethod();
            result.Name = methodInfo.Name;
            result.ReturnType = new CodeTypeReference(methodInfo.ReturnType);
            if (methodInfo.IsGenericMethod)
            {
                methodInfo.GetGenericArguments().ForEach(arg =>
                {
                    result.TypeParameters.Add(arg.Name);
                });
            }
            methodInfo.GetParameters().ForEach(param =>
            {
                result.Parameters.Add(new CodeParameterDeclarationExpression()
                {
                    Type = new CodeTypeReference(param.ParameterType),
                    Name = param.Name
                });
            });
            return result;
        }

        [EnvironmentPermissionAttribute(SecurityAction.Demand)]
        public static string GenericClassNameToString(Type type, CodeDomProvider provider)
        {
            Contract.Requires<ArgumentNullException>(provider != null, "provider");
            return provider.GetTypeOutput(new CodeTypeReference(type));
        }
    }
}
